from sqlalchemy.orm import Session
from sqlalchemy import and_, or_
from datetime import datetime, timedelta
from typing import List, Optional
from app.models.flight import Flight, FlightStatus
from app.schemas.flight import FlightCreate, FlightUpdate

class FlightService:
    def __init__(self, db: Session):
        self.db = db

    def get_flights(
        self,
        departure_city: Optional[str] = None,
        arrival_city: Optional[str] = None,
        departure_date: Optional[str] = None,
        airline: Optional[str] = None,
        skip: int = 0,
        limit: int = 100
    ) -> List[Flight]:
        query = self.db.query(Flight)
        
        if departure_city:
            query = query.filter(Flight.departure_city.ilike(f"%{departure_city}%"))
        
        if arrival_city:
            query = query.filter(Flight.arrival_city.ilike(f"%{arrival_city}%"))
        
        if departure_date:
            try:
                date_obj = datetime.strptime(departure_date, "%Y-%m-%d")
                start_date = date_obj.replace(hour=0, minute=0, second=0, microsecond=0)
                end_date = start_date + timedelta(days=1)
                query = query.filter(
                    and_(
                        Flight.departure_time >= start_date,
                        Flight.departure_time < end_date
                    )
                )
            except ValueError:
                # 如果日期格式无效，忽略此过滤条件
                pass
        
        if airline:
            query = query.filter(Flight.airline.ilike(f"%{airline}%"))
        
        return query.offset(skip).limit(limit).all()

    def get_flight_by_id(self, flight_id: int) -> Optional[Flight]:
        return self.db.query(Flight).filter(Flight.id == flight_id).first()

    def get_flight_by_number(self, flight_number: str) -> Optional[Flight]:
        return self.db.query(Flight).filter(Flight.flight_number == flight_number).first()

    def create_flight(self, flight: FlightCreate) -> Flight:
        db_flight = Flight(**flight.dict())
        self.db.add(db_flight)
        self.db.commit()
        self.db.refresh(db_flight)
        return db_flight

    def update_flight(self, flight_id: int, flight_update: FlightUpdate) -> Optional[Flight]:
        db_flight = self.get_flight_by_id(flight_id)
        if not db_flight:
            return None
        
        update_data = flight_update.dict(exclude_unset=True)
        for field, value in update_data.items():
            setattr(db_flight, field, value)
        
        db_flight.updated_at = datetime.utcnow()
        self.db.commit()
        self.db.refresh(db_flight)
        return db_flight

    def update_flight_status(self, flight_id: int, status: FlightStatus) -> Optional[Flight]:
        db_flight = self.get_flight_by_id(flight_id)
        if not db_flight:
            return None
        
        db_flight.status = status
        db_flight.updated_at = datetime.utcnow()
        self.db.commit()
        self.db.refresh(db_flight)
        return db_flight

    def delete_flight(self, flight_id: int) -> bool:
        db_flight = self.get_flight_by_id(flight_id)
        if not db_flight:
            return False
        
        self.db.delete(db_flight)
        self.db.commit()
        return True

    def check_availability(self, flight_id: int, requested_seats: int = 1) -> bool:
        flight = self.get_flight_by_id(flight_id)
        if not flight:
            return False
        
        return flight.available_seats >= requested_seats

    def reserve_seats(self, flight_id: int, seat_count: int = 1) -> bool:
        flight = self.get_flight_by_id(flight_id)
        if not flight or flight.available_seats < seat_count:
            return False
        
        flight.available_seats -= seat_count
        flight.updated_at = datetime.utcnow()
        self.db.commit()
        return True

    def release_seats(self, flight_id: int, seat_count: int = 1) -> bool:
        flight = self.get_flight_by_id(flight_id)
        if not flight:
            return False
        
        flight.available_seats += seat_count
        flight.updated_at = datetime.utcnow()
        self.db.commit()
        return True